import { _decorator, Component, Animation, SpriteFrame } from 'cc'
import { FSM_PARAMS_TYPE_ENUM, PARAMS_NAME_ENUM } from '../Enum'
import State from '../Base/State'
import { SubStateMachine } from './SubStateMachine'
const { ccclass, property } = _decorator

/**
 * Predefined variables
 * Name = StateMachine
 * DateTime = Sat Jul 09 2022 20:20:36 GMT+0800 (中国标准时间)
 * Author = Zero_Y
 * FileBasename = StateMachine.ts
 * FileBasenameNoExtension = StateMachine
 * URL = db://assets/Scripts/Base/StateMachine.ts
 * ManualUrl = https://docs.cocos.com/creator/3.4/manual/zh/
 *
 */

type ParamsValueType = boolean | number

export interface IParamsValue {
  type: FSM_PARAMS_TYPE_ENUM
  value: ParamsValueType
}
export const initParamsTrigger = () => {
  return {
    type: FSM_PARAMS_TYPE_ENUM.TRIGGER,
    value: false,
  }
}

export const initParamsNumber = () => {
  return {
    type: FSM_PARAMS_TYPE_ENUM.NUMBER,
    value: 0,
  }
}

@ccclass('StateMachine')
export abstract class StateMachine extends Component {
  // 当前选中的动画
  private _currentState: State | SubStateMachine = null
  // 参数列表
  params: Map<string, IParamsValue> = new Map()
  // 状态机列表
  stateMachines: Map<string, State | SubStateMachine> = new Map()
  // 动画组件
  animationComponent: Animation
  // 需要等待加载的列表
  waitingList: Array<Promise<SpriteFrame[]>> = []

  get currentState() {
    return this._currentState
  }

  set currentState(newState) {
    this._currentState = newState
    this._currentState.run()
  }

  getParams(paramsName: string) {
    if (this.params.has(paramsName)) {
      return this.params.get(paramsName).value
    }
  }
  setParams(paramsName: string, value: ParamsValueType) {
    if (this.params.has(paramsName)) {
      this.params.get(paramsName).value = value
      this.run()
      this.resetTrigger()
    }
  }

  resetTrigger() {
    for (const [_, value] of this.params) {
      if (value.type === FSM_PARAMS_TYPE_ENUM.TRIGGER) {
        value.value = false
      }
    }
  }

  abstract run(): void
  abstract init(): void
}
